<template>
  <div class="tracks-container">
    <!-- 其他人员的音频轨道 -->
    <div class="track romote-tracks">
      <div
        v-for="(track, index) in subscribedTracks"
        :key="`remote-${index}`"
        class="romote-track-item"
      >
        <div
          :class="{ 'romote-camera': track.tag === 'camera' }"
          :ref="
            (el) => {
              setRemoteRef(el, index)
            }
          "
        ></div>
        <span class="track-name">
          {{ track.userID }}
        </span>
      </div>
    </div>
    <!-- 自身轨道 -->
    <div class="track self-track">
      <div ref="cameraRef"></div>
      <div ref="microphoneRef"></div>
      <div class="self-track-icon">
        <img :src="getMicrophoneIcon" alt="" @click="handleMicrophone" />
        <img :src="getCameraIcon" alt="" @click="handleCamera" />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, nextTick, onMounted, ref, toRaw, watch, type PropType } from 'vue'
import Track from '../models/Track'
import trunOnCamera from '@/assets/icons/trun-on-camera.svg'
import trunOffCamera from '@/assets/icons/trun-off-camera.svg'
import trunOnMicrophone from '@/assets/icons/trun-on-microphone.svg'
import trunOffMicrophone from '@/assets/icons/trun-off-microphone.svg'
import { RoomStore } from '../roomStore'

const props = defineProps({
  roomStore: {
    type: Object as PropType<RoomStore>,
  },
  tracks: {
    type: Array as PropType<Track[]>,
    default: () => [],
  },
  subscribedTracks: {
    type: Array as PropType<Track[]>,
    default: () => [],
  },
  addShouldResumedTracks: {
    type: Function as PropType<(track: Track) => void>,
    default: () => void 0,
  },
})

const cameraRef = ref<HTMLDivElement | null>(null)
const microphoneRef = ref<HTMLDivElement | null>(null)
const remoteRefs = ref<Array<HTMLDivElement | null>>([])
const getMicrophoneIcon = computed(() =>
  !props.roomStore!.publishedAudioTracks().some((v) => !v.muted)
    ? trunOffMicrophone
    : trunOnMicrophone,
)
const getCameraIcon = computed(() =>
  !props.roomStore!.publishedCameraTracks().some((v) => !v.muted) ? trunOffCamera : trunOnCamera,
)

// 设置远程轨道的引用
const setRemoteRef = (el: HTMLDivElement | null, index: number) => {
  remoteRefs.value[index] = el
}

// 初始化自身轨道
watch(
  () => props.tracks,
  (newTracks) => {
    if (newTracks && newTracks.length) {
      nextTick(initLocalTracks)
    }
  },
  { immediate: true },
)

// 初始化远程轨道
watch(
  () => props.subscribedTracks,
  (newTracks) => {
    if (newTracks && newTracks.length) {
      remoteRefs.value = new Array(newTracks.length).fill(null)
      nextTick(initRemoteTracks)
    }
  },
  { immediate: true },
)
// 初始化自身轨道
const initLocalTracks = () => {
  if (!props.tracks.length) return

  // 清空容器
  if (cameraRef.value) cameraRef.value.innerHTML = ''
  if (microphoneRef.value) microphoneRef.value.innerHTML = ''

  // 分别处理视频轨道和音频轨道
  props.tracks.forEach((track) => {
    if (track.rtcTrack.isVideo() && !track.muted && cameraRef.value) {
      playTrack(track, cameraRef.value, 'self')
    } else if (track.rtcTrack.isAudio() && !track.muted && microphoneRef.value) {
      playTrack(track, microphoneRef.value, 'self')
    }
  })
}
// 初始化远程轨道
const initRemoteTracks = () => {
  if (!props.subscribedTracks.length || !remoteRefs.value.length) return

  // 处理每个远程音频轨道
  props.subscribedTracks.forEach((track, index) => {
    const container = remoteRefs.value[index]
    const Track = toRaw(track)
    if (container && !Track.muted) {
      container.innerHTML = '' // 清空容器
      playTrack(Track, container, 'remote')
    }
  })
}
// 播放轨道
const playTrack = (track: Track, container: HTMLDivElement, type: 'self' | 'remote') => {
  // 如果这是本地麦克风采集的音频 Track，我们就不播放它
  if (track.rtcTrack.isAudio() && type === 'self') {
    return
  }
  track.rtcTrack.play(container, { mirror: true }).catch((e) => {
    props.addShouldResumedTracks?.(track)
  })
}

// 开启、禁用麦克风
const handleMicrophone = () => {
  props.roomStore!.toggleMutePublishedAudio()
}
// 开启、禁用摄像头
const handleCamera = () => {
  props.roomStore!.toggleMutePublishedCamera()
}

onMounted(() => {
  initLocalTracks()
  if (props.subscribedTracks.length) {
    remoteRefs.value = new Array(props.subscribedTracks.length).fill(null)
    nextTick(initRemoteTracks)
  }
})
</script>
<style lang="less" scoped>
.tracks-container {
  display: flex;
  width: 100%;
  height: 100%;
  .track {
    display: flex;
    justify-content: center;
    padding: 5px;
    width: 100%;
    /deep/ video {
      width: 200px !important;
      height: 150px !important;
    }
  }
  .self-track {
    position: relative;
    /deep/ video {
      width: auto !important;
      height: 100% !important;
    }
    .self-track-icon {
      position: absolute;
      display: flex;
      justify-content: center;
      bottom: 20px;
      left: 0;
      gap: 20px;
      width: 100%;
      img {
        width: 24px;
        height: 24px;
        cursor: pointer;
      }
    }
  }
  .romote-tracks {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: 5px;
    position: absolute;
    left: 0;
    bottom: 200px;
    width: 50vw;
    max-width: 100vw;
    z-index: 99;
    // .romote-camera /deep/ video {
    //   height: 200px !important;
    //   width: auto !important;
    // }
    .romote-track-item {
      position: relative;
      .track-name {
        position: absolute;
        top: 5px;
        left: 5px;
        color: #fff;
      }
    }
  }
}
</style>
